#if defined( __VXWORKS__ )
#include "vxWorks.h"
#include "ioLib.h"
#include "intLib.h"
#include "tyLib.h"
#include "sioLib.h"
#include "iv.h"
#include "logLib.h"
#elif defined( __LINUX__ )
#include <stdio.h>
#include <fcntl.h>
#include <termios.h>
#include "stdio.h"
#include "string.h"
#endif

#define SERIAL_PORT "/dev/ttyS0"
int  sioFd;  //  文件描述符

void sioInit( ) {
  //  串口设备名称，波特率，数据位，停止位，校验
  sioFd = sioOpen( "/tyCo/0",
                   SIO_BAU_9600,
                   SIO_DATA_BITS_8 | SIO_PARITY_NONE | SIO_STOP_BITS_1 );
  if ( sioFd == ERROR ) {
    perror( "sioOpen failed" );
    return;
  }

  //  设置串口为阻塞模式
  sioIoctl( sioFd, SIO_MODE_INT_ON_RX_AND_TX_EMPTY, 0 );
}
void sioSend( char* data ) {
  int len     = strlen( data );
  int written = sioWrite( sioFd, data, len );
  if ( written != len ) {
    perror( "sioWrite failed" );
  }
}
void sioReceive( char* buffer, int size ) {
  int readCount = sioRead( sioFd, buffer, size );
  if ( readCount < 0 ) {
    perror( "sioRead failed" );
  } else {
    buffer[readCount] = '\0';  //  确保字符串正确终止
  }
}

int main( ) {
  int            fd;
  struct termios options;
  speed_t        baudrate = B9600;
  int            status;
  char           buffer[64];
  int            bytes_read;

  //  打开串口
  fd = open( SERIAL_PORT, O_RDWR | O_NOCTTY );
  if ( fd < 0 ) {
    perror( "open_port: Unable to open serial port - " );
    return -1;
  }

  //  获取并配置串口选项
  tcgetattr( fd, &options );
  cfsetispeed( &options, baudrate );
  cfsetospeed( &options, baudrate );
  options.c_cflag |= ( CLOCAL | CREAD );
  options.c_cflag &= ~CSIZE;
  options.c_cflag |= CS8;
  options.c_cflag &= ~PARENB;
  options.c_cflag &= ~CSTOPB;

  //  设置串口选项
  status = tcsetattr( fd, TCSANOW, &options );
  if ( status != 0 ) {
    perror( "tcsetattr" );
    return -1;
  }

  //  写入数据到串口
  const char* data = "Hello, VxWorks Serial!\n";
  write( fd, data, strlen( data ) );

  //  从串口读取数据
  bytes_read = read( fd, buffer, sizeof( buffer ) );
  if ( bytes_read > 0 ) {
    buffer[bytes_read] = '\0';  //  确保字符串以 null 结尾
    printf( "Read: %s", buffer );
  }

  //  关闭串口
  close( fd );

  return 0;
}

//

#include "vxWorks.h"
#include "stdio.h"
#include "ioLib.h"
#include "taskLib.h"
#include "sioLib.h"
#include "sdLib.h"
#include "semLib.h"
#include "msgQLib.h"

char wbuf[] = "hello";

#define DEV_NAME          "/tyCo/2"
#define MAX_BUF_SIZE      20
#define SD_COMMDATA_NAME  "share_data"
#define SD_COMMDATA_MUTEX "share_sem"
#define SHARE_DATA_LENGTH 20

typedef struct unix_clock_struct {
  UINT32 sec;     /* ms */
  UINT32 msec;    /* s */
  UINT8  quality; /* 时标质量 */
} UNIX_CLOCK_STRUCT;

char*  comdata;
int    set_serial( int fd );
SEM_ID mutexComdata;

void   taskUart( void );
int    main( void ) {
  int  ret;
  int  sdCommId;
  char r_buff[MAX_BUF_SIZE];

  mutexComdata = semOpen( SD_COMMDATA_MUTEX,
                          SEM_TYPE_MUTEX,
                          SEM_FULL,
                          SEM_Q_PRIORITY | SEM_DELETE_SAFE | SEM_INVERSION_SAFE,
                          OM_CREATE | OM_DELETE_ON_LAST_CLOSE,
                          NULL );
  if ( mutexComdata == NULL ) {
    /*致命错误，无法创建互斥锁*/
    printf( "ERROR TO OPEN SD_COMMDATA_MUTEX\n" );
    taskExit( 0 );
  }

  /* 申请公共数据共享内存  */
  sdCommId = sdOpen( SD_COMMDATA_NAME,
                     SD_LINGER,
                     OM_CREATE,
                     SHARE_DATA_LENGTH,
                     0,
                     SD_ATTR_RW | SD_CACHE_OFF,
                     &comdata );
  if ( sdCommId == NULL ) {
    /*致命错误，无法分配公共数据内存，报错退出*/
    printf( "ERROR TO OPEN SD_COMMDATA\n" );
    taskExit( 0 );
  }

  if ( ( ret = taskSpawn( "taskUart",
                          90,
                          0x100,
                          20000,
                          ( FUNCPTR )taskUart,
                          0,
                          0,
                          0,
                          0,
                          0,
                          0,
                          0,
                          0,
                          0,
                          0 ) )
       < 0 ) {
    printf( "taskSpawn failed:ret = %s\n" );
  }

  //  return 0;
}

void taskUart( void ) {
  int               ret;
  int               fd = -1;
  UNIX_CLOCK_STRUCT w_buff;

  if ( ( fd = open( DEV_NAME, O_RDWR, 0 ) ) < 0 ) {
    printf( "open %s failed.\n", DEV_NAME );
  }

  /*配置串口参数*/
  if ( ( ret = set_serial( fd ) ) < 0 ) {
    printf( "ret = %d\nset_serial failed.\n" );
  }

  while ( 1 ) {
    semRTake( mutexComdata, WAIT_FOREVER );
#if 0
        /*清空输入输出缓冲*/
        if((ret = ioctl(fd, FIOFLUSH, 0))<0)
        {
            printf(" ret = %d\nset FIOFLUSH failed.\n",ret);
        }


        memset(r_buff,0,sizeof(r_buff));
        /*读取串口中的值*/
        if((ret = read(fd,r_buff,sizeof(r_buff)))<0)
        {
            printf("ret = %d:read %s failed.\n",ret,DEV_NAME);
        }
        else
            printf("Received:%s\n",r_buff);
#endif

#if 1
    /*清空输入输出缓冲*/
    if ( ( ret = ioctl( fd, FIOFLUSH, 0 ) ) < 0 ) {
      printf( " ret = %d\nset FIOFLUSH failed.\n", ret );
    }

    if ( NULL == bzero( &w_buff, sizeof( w_buff ) ) ) {
      printf( "memset failed.\n" );
    }

    if ( NULL == memcpy( &w_buff, comdata, sizeof( w_buff ) ) ) {
      printf( "memset failed.\n" );
    }

    if ( &w_buff != NULL ) {
      /*往串口中写值*/
      //  if((ret = write(fd, wbuf, sizeof(wbuf)))<0)
      if ( ( ret = write( fd, &w_buff.sec, sizeof( ret ) ) ) < 0 ) {
        printf( "ret = %d:write %s failed.\n", ret, DEV_NAME );
      } else {
        printf( "write success:%d\n", w_buff.sec );
      }
    }

    semGive( mutexComdata );
#endif
    taskDelay( sysClkRateGet( ) * 2 );
  }
}

int set_serial( int fd ) {
  int error = -1;
  int ok    = 0;
  int ret;

  if ( fd < 0 ) {
    printf( "error:fd is %d\n", fd );
  }
  /*设定波特率为9600*/
  if ( ( ret = ioctl( fd, FIOBAUDRATE, 9600 ) ) < 0 ) {
    printf( "ret = %d\n set baudrate failed\n", ret );
    return error;
  }

  /*设定：数据位为8，无奇偶校验，1位停止位*/
  /*CLOCAL:忽略modem控制信号
   * CREAD：启动接收器
   * CS8:设定数据位为8*/
  if ( ( ret = ioctl( fd, SIO_HW_OPTS_SET, CREAD | CS8 | CLOCAL ) ) < 0 ) {
    printf( "ret = %d\nset SIO_HW_OPTS_SET failed.\n" );
    return error;
  }

  return ok;
}
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>

//  定义Modbus RTU帧结构
typedef struct {
  unsigned char  address;        //  从站地址
  unsigned char  function_code;  //  功能码
  unsigned short start_address;  //  开始地址
  unsigned short quantity;       //  寄存器数量
  unsigned char  error_check;    //  错误校验（CRC）
} ModbusRTURequest;

//  定义Modbus RTU响应结构
typedef struct {
  unsigned char  address;        //  从站地址
  unsigned char  function_code;  //  功能码
  unsigned short byte_count;     //  字节数
  unsigned char  data[256];      //  数据字段，最多256个字节
  unsigned char  error_check;    //  错误校验（CRC）
} ModbusRTUResponse;

//  计算CRC校验
unsigned char calculate_crc( const unsigned char* data, int length ) {
  unsigned char crc_hi = 0xFF;
  unsigned char crc_lo = 0xFF;

  while ( length-- ) {
    crc_hi ^= *data++;
    for ( int i = 0; i < 8; i++ ) {
      if ( crc_hi & 0x01 ) {
        crc_hi >>= 1;
        crc_hi ^= 0xA0;
      } else {
        crc_hi >>= 1;
      }
      if ( crc_lo & 0x01 ) {
        crc_lo >>= 1;
        crc_lo ^= 0xA0;
      } else {
        crc_lo >>= 1;
      }
    }
  }

  return crc_hi;
}

//  处理Modbus RTU请求
int handle_request( int                fd,
                    ModbusRTURequest*  request,
                    ModbusRTUResponse* response ) {
  //  根据请求的功能码处理数据
  switch ( request->function_code ) {
  case 0x03:  //  读保持寄存器
    //  假设数据已经存储在某个地方，这里简单模拟
    for ( int i = 0; i < request->quantity; i++ ) {
      response->data[i]
        = ( request->start_address + i ) % 256;  //  简单的模拟数据
    }
    response->byte_count = request->quantity;
    break;
  //  添加其他功能码的处理...
  default:
    response->function_code
      = 0x80 | request->function_code;  //  设置功能码为异常响应
    response->byte_count = 0;
    break;
  }

  //  设置从站地址和错误校验
  response->address     = request->address;
  response->error_check = calculate_crc( ( unsigned char* )response,
                                         sizeof( ModbusRTUResponse ) - 1 );

  //  发送响应
  if ( write( fd, response, sizeof( ModbusRTUResponse ) ) < 0 ) {
    perror( "write failed" );
    return -1;
  }

  return 0;
}

int main( ) {
  int               serial_fd;
  struct termios    options;
  ModbusRTURequest  request;
  ModbusRTUResponse response;
  unsigned char     buffer[1024];
  int               bytes_read;

  //  打开串口
  serial_fd = open( "/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY );
  if ( serial_fd < 0 ) {
    perror( "open_port: Unable to open serial port" );
    return 1;
  }

  //  配置串口
  tcgetattr( serial_fd, &options );
  cfsetispeed( &options, B9600 );
  cfsetospeed( &options, B9600 );
  options.c_cflag;
}